home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qe4 / map.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-18  |  13.2 KB  |  640 lines

  1. // map.c
  2.  
  3. #include "qe3.h"
  4.  
  5. qboolean    modified;        // for quit confirmation (0 = clean, 1 = unsaved,
  6.                             // 2 = autosaved, but not regular saved) 
  7.  
  8. char        currentmap[1024];
  9.  
  10. brush_t    active_brushes;        // brushes currently being displayed
  11. brush_t    selected_brushes;    // highlighted
  12. face_t    *selected_face;
  13. brush_t    *selected_face_brush;
  14. brush_t    filtered_brushes;    // brushes that have been filtered or regioned
  15.  
  16. entity_t    entities;        // head/tail of doubly linked list
  17.  
  18. entity_t    *world_entity;
  19.  
  20. void AddRegionBrushes (void);
  21. void RemoveRegionBrushes (void);
  22.  
  23. /*
  24. =============================================================
  25.  
  26.   Cross map selection saving
  27.  
  28.   this could fuck up if you have only part of a complex entity selected...
  29. =============================================================
  30. */
  31.  
  32. brush_t        between_brushes;
  33. entity_t    between_entities;
  34.  
  35.  
  36. void Map_SaveBetween (void)
  37. {
  38.     brush_t        *b;
  39.     entity_t    *e, *e2;
  40.  
  41.     between_brushes.next = selected_brushes.next;
  42.     between_brushes.prev = selected_brushes.prev;
  43.     between_brushes.next->prev = &between_brushes;
  44.     between_brushes.prev->next = &between_brushes;
  45.  
  46.     between_entities.next = between_entities.prev = &between_entities;
  47.     selected_brushes.next = selected_brushes.prev = &selected_brushes;
  48.  
  49.     for (b=between_brushes.next ; b != &between_brushes ; b=b->next)
  50.     {
  51.         e = b->owner;
  52.         if (e == world_entity)
  53.             b->owner = NULL;
  54.         else
  55.         {
  56.             for (e2=between_entities.next ; e2 != &between_entities ; e2=e2->next)
  57.                 if (e2 == e)
  58.                     goto next;    // allready got the entity
  59.             // move the entity over
  60.             e->prev->next = e->next;
  61.             e->next->prev = e->prev;
  62.             e->next = between_entities.next;
  63.             e->prev = &between_entities;
  64.             e->next->prev = e;
  65.             e->prev->next = e;
  66.         }
  67. next: ;
  68.     }
  69. }
  70.  
  71. void Map_RestoreBetween (void)
  72. {
  73.     entity_t    *head, *tail;
  74.     brush_t        *b;
  75.  
  76.     if (!between_brushes.next)
  77.         return;
  78.  
  79.     for (b=between_brushes.next ; b != &between_brushes ; b=b->next)
  80.     {
  81.         if (!b->owner)
  82.         {
  83.             b->owner = world_entity;
  84.             b->onext = world_entity->brushes.onext;
  85.             b->oprev = &world_entity->brushes;
  86.             b->onext->oprev = b;
  87.             b->oprev->onext = b;
  88.         }
  89.     }
  90.  
  91.     selected_brushes.next = between_brushes.next;
  92.     selected_brushes.prev = between_brushes.prev;
  93.     selected_brushes.next->prev = &selected_brushes;
  94.     selected_brushes.prev->next = &selected_brushes;
  95.  
  96.     head = between_entities.next;
  97.     tail = between_entities.prev;
  98.  
  99.     if (head != tail)
  100.     {
  101.         entities.prev->next = head;
  102.         head->prev = entities.prev;
  103.         tail->next = &entities;
  104.         entities.prev = tail;
  105.     }
  106.  
  107.     between_brushes.next = NULL;
  108.     between_entities.next = NULL;
  109. }
  110.  
  111. //============================================================================
  112.  
  113. void Map_BuildBrushData(void)
  114. {
  115.     brush_t    *b, *next;
  116.  
  117.     if (active_brushes.next == NULL)
  118.         return;
  119.  
  120.     Sys_BeginWait ();    // this could take a while
  121.  
  122.     for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=next)
  123.     {
  124.         next = b->next;
  125.         Brush_Build( b );
  126.         if (!b->brush_faces)
  127.         {
  128.             Brush_Free (b);
  129.             Sys_Printf ("Removed degenerate brush\n");
  130.         }
  131.     }
  132.  
  133.     Sys_EndWait();
  134. }
  135.  
  136. entity_t *Map_FindClass (char *cname)
  137. {
  138.     entity_t    *ent;
  139.  
  140.     for (ent = entities.next ; ent != &entities ; ent=ent->next)
  141.     {
  142.         if (!strcmp(cname, ValueForKey (ent, "classname")))
  143.             return ent;
  144.     }
  145.     return NULL;
  146. }
  147.  
  148. /*
  149. ================
  150. Map_Free
  151. ================
  152. */
  153. void Map_Free (void)
  154. {
  155.     if (selected_brushes.next &&
  156.         (selected_brushes.next != &selected_brushes) )
  157.     {
  158.         if (MessageBox(g_qeglobals.d_hwndMain, "Copy selection?", "", MB_YESNO) == IDYES)
  159.             Map_SaveBetween ();
  160.     }
  161.  
  162.     Texture_ClearInuse ();
  163.     Pointfile_Clear ();
  164.     strcpy (currentmap, "unnamed.map");
  165.     Sys_SetTitle (currentmap);
  166.     g_qeglobals.d_num_entities = 0;
  167.  
  168.     if (!active_brushes.next)
  169.     {    // first map
  170.         active_brushes.prev = active_brushes.next = &active_brushes;
  171.         selected_brushes.prev = selected_brushes.next = &selected_brushes;
  172.         filtered_brushes.prev = filtered_brushes.next = &filtered_brushes;
  173.  
  174.         entities.prev = entities.next = &entities;
  175.     }
  176.     else
  177.     {
  178.         while (active_brushes.next != &active_brushes)
  179.             Brush_Free (active_brushes.next);
  180.         while (selected_brushes.next != &selected_brushes)
  181.             Brush_Free (selected_brushes.next);
  182.         while (filtered_brushes.next != &filtered_brushes)
  183.             Brush_Free (filtered_brushes.next);
  184.  
  185.         while (entities.next != &entities)
  186.             Entity_Free (entities.next);
  187.     }
  188.  
  189.     world_entity = NULL;
  190. }
  191.  
  192. /*
  193. ================
  194. Map_LoadFile
  195. ================
  196. */
  197. void Map_LoadFile (char *filename)
  198. {
  199.     char        *buf;
  200.     entity_t    *ent;
  201.     char         temp[1024];
  202.  
  203.     Sys_BeginWait ();
  204.  
  205.     SetInspectorMode(W_CONSOLE);
  206.  
  207.     QE_ConvertDOSToUnixName( temp, filename );
  208.     Sys_Printf ("Map_LoadFile: %s\n", temp );
  209.  
  210.     Map_Free ();
  211.  
  212.     g_qeglobals.d_parsed_brushes = 0;
  213.     strcpy (currentmap, filename);
  214.     LoadFile (filename, (void **)&buf);
  215.  
  216.     StartTokenParsing (buf);
  217.  
  218.     g_qeglobals.d_num_entities = 0;
  219.  
  220.     while (1)
  221.     {
  222.         ent = Entity_Parse (false);
  223.         if (!ent)
  224.             break;
  225.         if (!strcmp(ValueForKey (ent, "classname"), "worldspawn"))
  226.         {
  227.             if (world_entity)
  228.                 Sys_Printf ("WARNING: multiple worldspawn\n");
  229.             world_entity = ent;
  230.         }
  231.         else
  232.         {
  233.             // add the entity to the end of the entity list
  234.             ent->next = &entities;
  235.             ent->prev = entities.prev;
  236.             entities.prev->next = ent;
  237.             entities.prev = ent;
  238.             g_qeglobals.d_num_entities++;
  239.         }
  240.     }
  241.  
  242.     free (buf);
  243.  
  244.     if (!world_entity)
  245.     {
  246.         Sys_Printf ("No worldspawn in map.\n");
  247.         Map_New ();
  248.         return;
  249.     }
  250.  
  251.     Sys_Printf ("--- LoadMapFile ---\n");
  252.     Sys_Printf ("%s\n", temp );
  253.  
  254.     Sys_Printf ("%5i brushes\n",  g_qeglobals.d_parsed_brushes );
  255.     Sys_Printf ("%5i entities\n", g_qeglobals.d_num_entities);
  256.  
  257.     Map_RestoreBetween ();
  258.  
  259.     Sys_Printf ("Map_BuildAllDisplayLists\n");
  260.     Map_BuildBrushData();
  261.  
  262.     //
  263.     // move the view to a start position
  264.     //
  265.     ent = Map_FindClass ("info_player_start");
  266.     if (!ent)
  267.         ent = Map_FindClass ("info_player_deathmatch");
  268.     camera.angles[PITCH] = 0;
  269.     if (ent)
  270.     {
  271.         GetVectorForKey (ent, "origin", camera.origin);
  272.         GetVectorForKey (ent, "origin", g_qeglobals.d_xy.origin);
  273.         camera.angles[YAW] = FloatForKey (ent, "angle");
  274.     }
  275.     else
  276.     {
  277.         camera.angles[YAW] = 0;
  278.         VectorCopy (vec3_origin, camera.origin);
  279.         VectorCopy (vec3_origin, g_qeglobals.d_xy.origin);
  280.     }
  281.  
  282.     Sys_UpdateWindows (W_ALL);
  283.  
  284.     Map_RegionOff ();
  285.  
  286.     modified = false;
  287.     Sys_SetTitle (temp);
  288.  
  289.     Texture_ShowInuse ();
  290.  
  291.     Sys_EndWait();
  292.  
  293. }
  294.  
  295. /*
  296. ===========
  297. Map_SaveFile
  298. ===========
  299. */
  300. void Map_SaveFile (char *filename, qboolean use_region )
  301. {
  302.     entity_t    *e, *next;
  303.     FILE        *f;
  304.     char         temp[1024];
  305.     int            count;
  306.  
  307.     QE_ConvertDOSToUnixName( temp, filename );
  308.  
  309.     if (!use_region)
  310.     {
  311.         char    backup[1024];
  312.  
  313.         // rename current to .bak
  314.         strcpy (backup, filename);
  315.         StripExtension (backup);
  316.         strcat (backup, ".bak");
  317.         _unlink (backup);
  318.         rename (filename, backup);
  319.     }
  320.  
  321.     Sys_Printf ("Map_SaveFile: %s\n", filename);
  322.  
  323.     f = fopen(filename, "w");
  324.     if (!f)
  325.     {
  326.         Sys_Printf ("ERROR!!!! Couldn't open %s\n", filename);
  327.         return;
  328.     }
  329.  
  330.     if (use_region)
  331.         AddRegionBrushes ();
  332.  
  333.     // write world entity first
  334.     Entity_Write (world_entity, f, use_region);
  335.  
  336.     // then write all other ents
  337.     count = 1;
  338.     for (e=entities.next ; e != &entities ; e=next)
  339.     {
  340.         fprintf (f, "// entity %i\n", count);
  341.         count++;
  342.         next = e->next;
  343.         if (e->brushes.onext == &e->brushes)
  344.             Entity_Free (e);    // no brushes left, so remove it
  345.         else
  346.             Entity_Write (e, f, use_region);
  347.     }
  348.  
  349.     fclose (f);
  350.  
  351.     if (use_region)
  352.         RemoveRegionBrushes ();
  353.  
  354.     Sys_Printf ("Saved.\n");
  355.     modified = false;
  356.  
  357.     if ( !strstr( temp, "autosave" ) )
  358.         Sys_SetTitle (temp);
  359.  
  360.     if (!use_region)
  361.     {
  362.         time_t    timer;
  363.         FILE    *f;
  364.  
  365.         time (&timer);
  366.         MessageBeep (MB_ICONEXCLAMATION);
  367.         f = fopen ("c:/tstamps.log", "a");
  368.         if (f)
  369.         {
  370.             fprintf (f, "%4i : %35s : %s", g_qeglobals.d_workcount, filename, ctime(&timer));
  371.             fclose (f);
  372.             g_qeglobals.d_workcount = 0;
  373.         }
  374.         fclose (f);
  375.         Sys_Status ("Saved.\n", 0);
  376.     }
  377. }
  378.  
  379. /*
  380. ===========
  381. Map_New
  382. ===========
  383. */
  384. void Map_New (void)
  385. {
  386.     Sys_Printf ("Map_New\n");
  387.     Map_Free ();
  388.     world_entity = qmalloc(sizeof(*world_entity));
  389.     world_entity->brushes.onext = 
  390.         world_entity->brushes.oprev = &world_entity->brushes;
  391.     SetKeyValue (world_entity, "classname", "worldspawn");
  392.     world_entity->eclass = Eclass_ForName ("worldspawn", true);
  393.  
  394.     camera.angles[YAW] = 0;
  395.     VectorCopy (vec3_origin, camera.origin);
  396.     camera.origin[2] = 48;
  397.     VectorCopy (vec3_origin, g_qeglobals.d_xy.origin);
  398.  
  399.     Map_RestoreBetween ();
  400.  
  401.     Sys_UpdateWindows (W_ALL);
  402.     modified = false;
  403. }
  404.  
  405.  
  406. /*
  407. ===========================================================
  408.  
  409.   REGION
  410.  
  411. ===========================================================
  412. */
  413.  
  414. qboolean    region_active;
  415. vec3_t    region_mins = {-4096, -4096, -4096};
  416. vec3_t    region_maxs = {4096, 4096, 4096};
  417.  
  418. brush_t    *region_sides[4];
  419.  
  420. /*
  421. ===========
  422. AddRegionBrushes
  423.  
  424. a regioned map will have temp walls put up at the region boundary
  425. ===========
  426. */
  427. void AddRegionBrushes (void)
  428. {
  429.     vec3_t    mins, maxs;
  430.     int        i;
  431.     texdef_t    td;
  432.  
  433.     if (!region_active)
  434.         return;
  435.  
  436.     memset (&td, 0, sizeof(td));
  437.     strcpy (td.name, "REGION");
  438.  
  439.     mins[0] = region_mins[0] - 16;
  440.     maxs[0] = region_mins[0] + 1;
  441.     mins[1] = region_mins[1] - 16;
  442.     maxs[1] = region_maxs[1] + 16;
  443.     mins[2] = -2048;
  444.     maxs[2] = 2048;
  445.     region_sides[0] = Brush_Create (mins, maxs, &td);
  446.  
  447.     mins[0] = region_maxs[0] - 1;
  448.     maxs[0] = region_maxs[0] + 16;
  449.     region_sides[1] = Brush_Create (mins, maxs, &td);
  450.  
  451.     mins[0] = region_mins[0] - 16;
  452.     maxs[0] = region_maxs[0] + 16;
  453.     mins[1] = region_mins[1] - 16;
  454.     maxs[1] = region_mins[1] + 1;
  455.     region_sides[2] = Brush_Create (mins, maxs, &td);
  456.  
  457.     mins[1] = region_maxs[1] - 1;
  458.     maxs[1] = region_maxs[1] + 16;
  459.     region_sides[3] = Brush_Create (mins, maxs, &td);
  460.  
  461.     for (i=0 ; i<4 ; i++)
  462.     {
  463.         Brush_AddToList (region_sides[i], &selected_brushes);
  464.         Entity_LinkBrush (world_entity, region_sides[i]);
  465.         Brush_Build( region_sides[i] );
  466.     }
  467. }
  468.  
  469. void RemoveRegionBrushes (void)
  470. {
  471.     int        i;
  472.  
  473.     if (!region_active)
  474.         return;
  475.     for (i=0 ; i<4 ; i++)
  476.         Brush_Free (region_sides[i]);
  477. }
  478.  
  479.  
  480. qboolean Map_IsBrushFiltered (brush_t *b)
  481. {
  482.     int        i;
  483.  
  484.     for (i=0 ; i<3 ; i++)
  485.     {
  486.         if (b->mins[i] > region_maxs[i])
  487.             return true;
  488.         if (b->maxs[i] < region_mins[i])
  489.             return true;
  490.     }
  491.     return false;
  492. }
  493.  
  494. /*
  495. ===========
  496. Map_RegionOff
  497.  
  498. Other filtering options may still be on
  499. ===========
  500. */
  501. void Map_RegionOff (void)
  502. {
  503.     brush_t    *b, *next;
  504.     int            i;
  505.  
  506.     region_active = false;
  507.     for (i=0 ; i<3 ; i++)
  508.     {
  509.         region_maxs[i] = 4096;
  510.         region_mins[i] = -4096;
  511.     }
  512.     
  513.     for (b=filtered_brushes.next ; b != &filtered_brushes ; b=next)
  514.     {
  515.         next = b->next;
  516.         if (Map_IsBrushFiltered (b))
  517.             continue;        // still filtered
  518.         Brush_RemoveFromList (b);
  519.         Brush_AddToList (b, &active_brushes);
  520.     }
  521.  
  522.     Sys_UpdateWindows (W_ALL);
  523. }
  524.  
  525. void Map_ApplyRegion (void)
  526. {
  527.     brush_t    *b, *next;
  528.  
  529.     region_active = true;
  530.     for (b=active_brushes.next ; b != &active_brushes ; b=next)
  531.     {
  532.         next = b->next;
  533.         if (!Map_IsBrushFiltered (b))
  534.             continue;        // still filtered
  535.         Brush_RemoveFromList (b);
  536.         Brush_AddToList (b, &filtered_brushes);
  537.     }
  538.  
  539.     Sys_UpdateWindows (W_ALL);
  540. }
  541.  
  542.  
  543. /*
  544. ========================
  545. Map_RegionSelectedBrushes
  546. ========================
  547. */
  548. void Map_RegionSelectedBrushes (void)
  549. {
  550.     Map_RegionOff ();
  551.  
  552.     region_active = true;
  553.     Select_GetBounds (region_mins, region_maxs);
  554.  
  555.     // move the entire active_brushes list to filtered_brushes
  556.     filtered_brushes.next = active_brushes.next;
  557.     filtered_brushes.prev = active_brushes.prev;
  558.     filtered_brushes.next->prev = &filtered_brushes;
  559.     filtered_brushes.prev->next = &filtered_brushes;
  560.  
  561.     // move the entire selected_brushes list to active_brushes
  562.     active_brushes.next = selected_brushes.next;
  563.     active_brushes.prev = selected_brushes.prev;
  564.     active_brushes.next->prev = &active_brushes;
  565.     active_brushes.prev->next = &active_brushes;
  566.  
  567.     // clear selected_brushes
  568.     selected_brushes.next = selected_brushes.prev = &selected_brushes;
  569.  
  570.     Sys_UpdateWindows (W_ALL);
  571. }
  572.  
  573.  
  574. /*
  575. ===========
  576. Map_RegionXY
  577. ===========
  578. */
  579. void Map_RegionXY (void)
  580. {
  581.     Map_RegionOff ();
  582.  
  583.     region_mins[0] = g_qeglobals.d_xy.origin[0] - 0.5*g_qeglobals.d_xy.width/g_qeglobals.d_xy.scale;
  584.     region_maxs[0] = g_qeglobals.d_xy.origin[0] + 0.5*g_qeglobals.d_xy.width/g_qeglobals.d_xy.scale;
  585.     region_mins[1] = g_qeglobals.d_xy.origin[1] - 0.5*g_qeglobals.d_xy.height/g_qeglobals.d_xy.scale;
  586.     region_maxs[1] = g_qeglobals.d_xy.origin[1] + 0.5*g_qeglobals.d_xy.height/g_qeglobals.d_xy.scale;
  587.     region_mins[2] = -4096;
  588.     region_maxs[2] = 4096;
  589.  
  590.     Map_ApplyRegion ();
  591. }
  592.  
  593. /*
  594. ===========
  595. Map_RegionTallBrush
  596. ===========
  597. */
  598. void Map_RegionTallBrush (void)
  599. {
  600.     brush_t    *b;
  601.  
  602.     if (!QE_SingleBrush ())
  603.         return;
  604.  
  605.     b = selected_brushes.next;
  606.  
  607.     Map_RegionOff ();
  608.  
  609.     VectorCopy (b->mins, region_mins);
  610.     VectorCopy (b->maxs, region_maxs);
  611.     region_mins[2] = -4096;
  612.     region_maxs[2] = 4096;
  613.  
  614.     Select_Delete ();
  615.     Map_ApplyRegion ();
  616. }
  617. /*
  618. ===========
  619. Map_RegionBrush
  620. ===========
  621. */
  622. void Map_RegionBrush (void)
  623. {
  624.     brush_t    *b;
  625.  
  626.     if (!QE_SingleBrush ())
  627.         return;
  628.  
  629.     b = selected_brushes.next;
  630.  
  631.     Map_RegionOff ();
  632.  
  633.     VectorCopy (b->mins, region_mins);
  634.     VectorCopy (b->maxs, region_maxs);
  635.  
  636.     Select_Delete ();
  637.     Map_ApplyRegion ();
  638. }
  639.  
  640.